package edu.hawaii.myisern.model;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;

/**
 * Tests the DataXml class.
 * 
 * @author Randy Cox
 * 
 */
public class TestDataXml {

  /** Test location. */
  public static final String TEST_DIR = System.getProperty("user.home") + "/.myisern/";

  /**
   * Test read write researcher methods.
   * 
   * @throws Exception if jaxb or IO error is encountered.
   */
  @Test
  public void testReadWriteResearcher() throws Exception {

    String name = "Researcher";
    String email = "Email";
    String org = "Org";
    String pict = "Pict";
    String bio = "Bio";
    Integer count = 10;

    // Set up record vars.
    List<MyResearcher> myResearchersWrite = new ArrayList<MyResearcher>();
    for (Integer i = 0; i < count; i++) {
      MyResearcher myresearcher = new MyResearcher();
      myresearcher.setName(name + i.toString());
      myresearcher.setEmail(email + i.toString());
      myresearcher.setOrganization(org + i.toString());
      myresearcher.setPictureLink(pict + i.toString());
      myresearcher.setBio(bio + i.toString());
      myResearchersWrite.add(myresearcher);
    }

    // Write data to xml file.
    DataXml.writeXmlResearchers(TEST_DIR + "test_researchers.xml", myResearchersWrite);

    // Read data from xml file.
    List<MyResearcher> myResearchersRead = DataXml.readXmlResearchers(TEST_DIR
        + "test_researchers.xml");

    // Test before and after round trip to xml files.
    for (Integer i = 0; i < count; i++) {
      MyResearcher expected = myResearchersWrite.get(i);
      MyResearcher result = myResearchersRead.get(i);
      assertEquals("Check researcher name", expected.getName(), result.getName());
      assertEquals("Check researcher email", expected.getEmail(), result.getEmail());
      assertEquals("Check researcher organization", expected.getOrganization(), result
          .getOrganization());
      assertEquals("Check researcher picture link", expected.getPictureLink(), result
          .getPictureLink());
      assertEquals("Check researcher bio", expected.getBio(), result.getBio());
    }

    // Delete test file.
    File file = new File(TEST_DIR + "test_researchers.xml");
    file.delete();
  }

  /**
   * Test read write organization methods.
   * 
   * @throws Exception if jaxb or IO error is encountered.
   */
  @Test
  public void testReadWriteOrganization() throws Exception {

    String name = "First Last ";
    String type = "Type";
    String contact = "Contact";
    String[] researchers = { "Reasearcher1", "Researcher2", "Researcher3" };
    String country = "Country";
    String[] keywords = { "Keyword1", "Keyword2", "Keyword3" };
    String description = "Description";
    String homePage = "Home Page";
    List<String> researcherList = new ArrayList<String>();
    researcherList.add("ResearchA");
    researcherList.add("ResearchB");
    researcherList.add("ResearchC");
    List<String> keywordList = new ArrayList<String>();
    keywordList.add("KeywordA");
    keywordList.add("KeywordB");
    keywordList.add("KeywordC");
    Integer count = 10;

    // Set up record vars.
    List<MyOrganization> myOrganizationsWrite = new ArrayList<MyOrganization>();
    for (Integer i = 0; i < count; i++) {
      MyOrganization organization = new MyOrganization();
      organization.setName(name + i.toString());
      organization.setType(type + i.toString());
      organization.setContact(contact + i.toString());
      organization.setAffiliatedResearchers(researcherList);
      organization.addAffiliatedResearcher(researchers[0] + i.toString());
      organization.addAffiliatedResearcher(researchers[1] + i.toString());
      organization.addAffiliatedResearcher(researchers[2] + i.toString());
      organization.setCountry(country + i.toString());
      organization.setResearchKeywords(keywordList);
      organization.addResearchKeyword(keywords[0] + i.toString());
      organization.addResearchKeyword(keywords[1] + i.toString());
      organization.addResearchKeyword(keywords[2] + i.toString());
      organization.setResearchDescription(description);
      organization.setHomePage(homePage + i.toString());
      myOrganizationsWrite.add(organization);
    }

    // Write data to xml file.
    DataXml.writeXmlOrganizations(TEST_DIR + "test_organizations.xml", myOrganizationsWrite);

    // Read data from xml file.
    List<MyOrganization> myOrganizationsRead = DataXml.readXmlOrganizations(TEST_DIR
        + "test_organizations.xml");

    // Test before and after round trip to xml files.
    for (Integer i = 0; i < count; i++) {
      MyOrganization expected = myOrganizationsWrite.get(i);
      MyOrganization result = myOrganizationsRead.get(i);
      assertEquals("Check researcher name", expected.getName(), result.getName());
      assertEquals("Check type.", expected.getType(), result.getType());
      assertEquals("Check contact.", expected.getContact(), result.getContact());
      assertEquals("Check resA.", expected.getAffiliatedResearchers().get(0), result
          .getAffiliatedResearchers().get(0));
      assertEquals("Check resA.", expected.getAffiliatedResearchers().get(1), result
          .getAffiliatedResearchers().get(1));
      assertEquals("Check resA.", expected.getAffiliatedResearchers().get(2), result
          .getAffiliatedResearchers().get(2));
      assertEquals("Check country.", expected.getCountry(), result.getCountry());
      assertEquals("Check keywordA.", expected.getResearchKeywords().get(0), result
          .getResearchKeywords().get(0));
      assertEquals("Check keywordA.", expected.getResearchKeywords().get(1), result
          .getResearchKeywords().get(1));
      assertEquals("Check keywordA.", expected.getResearchKeywords().get(2), result
          .getResearchKeywords().get(2));
      assertEquals("Check descripiton.", expected.getResearchDescription(), result
          .getResearchDescription());
      assertEquals("Check homepage.", expected.getHomePage(), result.getHomePage());
    }

    // Delete test file.
    File file = new File(TEST_DIR + "test_organizations.xml");
    file.delete();
  }

  /**
   * Test read write organization methods.
   * 
   * @throws Exception if jaxb or IO error is encountered.
   */
  @Test
  public void testReadWriteCollaboration() throws Exception {

    String name = "collaboration name ";
    String desc = "Desc";
    String[] organizations = { "Organization1", "Organization2", "Organization3" };
    String[] years = { "2000", "2001", "2002" };
    String[] types = { "Type1", "Type2", "Type3" };
    String[] outcomes = { "Outcome1", "Outcome2", "Outcome3" };
    List<String> orgList = new ArrayList<String>();
    orgList.add("OrgA");
    orgList.add("OrgB");
    orgList.add("OrgC");
    List<String> yearList = new ArrayList<String>();
    yearList.add("2003");
    yearList.add("2004");
    yearList.add("2005");
    List<String> typeList = new ArrayList<String>();
    typeList.add("TypeA");
    typeList.add("TypeB");
    typeList.add("TypeC");
    List<String> outcomeList = new ArrayList<String>();
    outcomeList.add("OutcomeA");
    outcomeList.add("OutcomeB");
    outcomeList.add("OutcomeC");
    Integer count = 10;

    // Set up record vars.
    List<MyCollaboration> myCollaborationsWrite = new ArrayList<MyCollaboration>();
    for (Integer i = 0; i < count; i++) {
      MyCollaboration collaboration = new MyCollaboration();
      collaboration.setName(name + i.toString());
      collaboration.setDescription(desc + i.toString());
      collaboration.setOrganizations(orgList);
      collaboration.addOrganization(organizations[0] + i.toString());
      collaboration.addOrganization(organizations[1] + i.toString());
      collaboration.addOrganization(organizations[2] + i.toString());
      collaboration.setYears(yearList);
      collaboration.addYear(years[0] + i.toString());
      collaboration.addYear(years[1] + i.toString());
      collaboration.addYear(years[2] + i.toString());
      collaboration.setTypes(typeList);
      collaboration.addType(types[0] + i.toString());
      collaboration.addType(types[1] + i.toString());
      collaboration.addType(types[2] + i.toString());
      collaboration.setOutcomes(outcomeList);
      collaboration.addOutcome(outcomes[0] + i.toString());
      collaboration.addOutcome(outcomes[1] + i.toString());
      collaboration.addOutcome(outcomes[2] + i.toString());
      myCollaborationsWrite.add(collaboration);
    }

    // Write data to xml file.
    DataXml.writeXmlCollaborations(TEST_DIR + "test_collaborations.xml", myCollaborationsWrite);

    // Read data from xml file.
    List<MyCollaboration> myCollaborationsRead = DataXml.readXmlCollaborations(TEST_DIR
        + "test_collaborations.xml");

    // Test before and after round trip to xml files.
    for (Integer i = 0; i < count; i++) {
      MyCollaboration expected = myCollaborationsWrite.get(i);
      MyCollaboration result = myCollaborationsRead.get(i);
      assertEquals("Check ID.", expected.getId(), result.getId());
      assertEquals("Check name.", expected.getName(), result.getName());
      assertEquals("Check desc.", expected.getDescription(), result.getDescription());
      assertEquals("Check orgA.", expected.getOrganizations().get(0), result.getOrganizations()
          .get(0));
      assertEquals("Check orgB.", expected.getOrganizations().get(1), result.getOrganizations()
          .get(1));
      assertEquals("Check orgC.", expected.getOrganizations().get(2), result.getOrganizations()
          .get(2));
      assertEquals("Check yearA.", expected.getYears().get(0), result.getYears().get(0));
      assertEquals("Check yearB.", expected.getYears().get(1), result.getYears().get(1));
      assertEquals("Check yearC.", expected.getYears().get(2), result.getYears().get(2));
      assertEquals("Check typeA.", expected.getTypes().get(0), result.getTypes().get(0));
      assertEquals("Check typeB.", expected.getTypes().get(1), result.getTypes().get(1));
      assertEquals("Check typeC.", expected.getTypes().get(2), result.getTypes().get(2));
      assertEquals("Check outcomeA.", expected.getOutcomes().get(0), result.getOutcomes().get(0));
      assertEquals("Check outcomeB.", expected.getOutcomes().get(1), result.getOutcomes().get(1));
      assertEquals("Check outcomeC.", expected.getOutcomes().get(2), result.getOutcomes().get(2));
    }

    // Delete test file.
    File file = new File(TEST_DIR + "test_collaborations.xml");
    file.delete();
  }

  /**
   * Test constructor.
   */
  @Test
  public void testConstructor() {
    DataXml dataXml = new DataXml();
    assertNotNull("Test object is not null", dataXml);
  }
}
